/**
 * @File name: init.c
 * @Synopsis:
 * @Author: xing.dai@aliyun.com
 * @Version: 0.0.1
 * @Date: 2018-12-21 21:38
 */

#include <stdio.h>
#include "init.h"

/* These two variables are defined in link script. */
extern struct config_init_t __config_init_start[];
extern struct config_init_t __config_init_pre_1_start[];
extern struct config_init_t __config_init_end[];

static struct config_init_t *init_levels[] = {
	__config_init_pre_1_start,
	__config_init_end
};

#ifdef SINGLE
void do_initcalls(int level)
{
	init_call *init_ptr = __config_init_start;
	int i;
	unsigned int *aaa = (unsigned int *)init_levels[0];

	for (i = 0; i < 20; i++)
	{
		printf("a:%p v:%x\n", aaa, *aaa);
		aaa++;
	}
	for(; init_ptr < __config_init_end; init_ptr++)
	{
		(*init_ptr)();
	}
}
#else
void do_initcalls(int level)
{
	struct config_init_t *info;
	int i;
	
	unsigned int *aaa = (unsigned int *)init_levels[0];
	
	printf("sizeof(ptr)=%ld\n", sizeof(int *));
	printf("sizeof(int)=%ld\n", sizeof(int));
	printf("sizeof(config)=%ld\n", sizeof(struct config_init_t));

	for (i = 0; i < 20; i++)
	{
		printf("a:%p v:%x\n", aaa, *aaa);
		aaa++;
	}
	
	for(info = init_levels[level]; info < init_levels[level + 1]; info++) {
		printf("info addr: %p value: %x.\n", info, *(unsigned int *)info);
		printf("info->init addr: %p.\n", info->init);
		info->init();
	}
}
#endif
